
#include "scenecreator.h"
#include <QDir>
#include <QProcess>
#include <QCoreApplication>
#include <QDebug>
#include <QImage>
#include <opencv/cv.h>
#include <opencv/highgui.h>
#include <string>
#include <iostream>

sceneCreator::sceneCreator(sceneDefinition* def)
{
    itsDefinition = def;
    if(itsDefinition->name==""){
        if(itsDefinition->sphericalSourceImage.fileName()!=""){
            itsDefinition->name = itsDefinition->sphericalSourceImage.fileName().section(".",0,0);
        }
        else if(itsDefinition->cubicSourceImages.size()>0){
            if(itsDefinition->cubicSourceImages.first().fileName()!=""){
                itsDefinition->name = itsDefinition->cubicSourceImages.first().fileName().section(".",0,0);
            }
        }
        else{
            itsDefinition->valid = false;
        }
    }
    ktransform.setFile(QCoreApplication::applicationDirPath()+"/ktransform.exe");
    kmakepreview.setFile(QCoreApplication::applicationDirPath()+"/kmakepreview.exe");
    src.setPath(QCoreApplication::applicationDirPath());
}

#ifdef Q_OS_WIN32

void sceneCreator::copyRequiredFiles(){
    QDir dir = itsDefinition->sceneDir;
    dir.cdUp();
    dir.cdUp();
    QString command="xcopy "+src.absolutePath()+"/templates/required"+" "+dir.absolutePath();
    command.replace("/","\\");
    command+=" /e /y";
    system(command.toLatin1().data());
}

#endif
#ifdef Q_OS_LINUX

void sceneCreator::copyRequiredFiles(){
    QDir dir = itsDefinition->sceneDir;
    dir.cdUp();
    dir.cdUp();

    QDir dir2 = src.absolutePath()+"/templates/required";
    QStringList files = dir2.entryList();
    for(int i=0;i<files.size();i++){
        QString name = files.at(i);
        if(name.at(0)!='.'){
            QString command="cp -r "+src.absolutePath()+"/templates/required/"+files.at(i)+" "+dir.absolutePath();
            QProcess *myProcess = new QProcess();
            myProcess->execute(command);
            delete myProcess;
        }

    }
}

#endif

void sceneCreator::makeViewer(){
    copyRequiredFiles();
    QString indexTemplate = readTemplate(itsDefinition->templateFile.dir().path()+"/indextemplate.xml");
    if(indexTemplate != NULL){
        indexTemplate=fillTemplate(indexTemplate);
    }
    saveTemplate(indexTemplate,itsDefinition->sceneDir.absolutePath()+"/../index.html");
    QString indexXmlTemplate = readTemplate(itsDefinition->templateFile.dir().path()+"/indexxmltemplate.xml");
    if(indexXmlTemplate != NULL){
        indexXmlTemplate=fillTemplate(indexXmlTemplate);
    }
    saveTemplate(indexXmlTemplate,itsDefinition->sceneDir.absolutePath()+"/../"+itsDefinition->name+".xml");
}

void sceneCreator::createItself(){
    if(itsDefinition->valid){
        createDirectory(itsDefinition->sceneDir.absolutePath());
        if(itsDefinition->cubicSourceImages.size()<6){
            makeCubic();
        }
        makePreview();
        QString tmplt = readTemplate(itsDefinition->templateFile.absoluteFilePath());
        if(tmplt != NULL){
            tmplt=fillTemplate(tmplt);
        }
        saveTemplate(tmplt,itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+".xml");

        //scene is created now create files to view it
        makeViewer();
    }

}

void sceneCreator::createDirectory(QString dirPath){
    if(!QDir().exists(dirPath)){
        QDir().mkpath(dirPath);
    }
}

#ifdef Q_OS_WIN32

void sceneCreator::makeCubic(){

    QString program = ktransform.absoluteFilePath();

    program +=" cube6 "
              +itsDefinition->sphericalSourceImage.filePath()+" "
              +itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name
              +" -jpegquality=100 -jpegsubsamp=422 -jpegoptimize";

    QProcess *myProcess = new QProcess(this);
    qDebug()<<program;
    myProcess->execute(program);

    QFileInfo cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_f.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_r.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_b.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_l.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_u.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_d.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
}

void sceneCreator::makePreview(){
    QString program = kmakepreview.absoluteFilePath();

    program +=" "+itsDefinition->sphericalSourceImage.filePath()+" "
              +"-o="+itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"preview.jpg";
    QProcess *myProcess = new QProcess(this);
    myProcess->execute(program);
}

#endif
#ifdef Q_OS_LINUX

void sceneCreator::makeCubic(){
    QFileInfo cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_f.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_r.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_b.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_l.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_u.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);
    cubeFace = itsDefinition->sceneDir.absolutePath()+"/"+itsDefinition->name+"_d.jpg";
    this->itsDefinition->cubicSourceImages.push_back(cubeFace);



    //reading template
    QFile file("./templates/sphere2cubic.pto");
    if(!file.open(QIODevice::ReadOnly)) {
        qDebug()<<"cannot read => sphere2cubic template";
    }
    QTextStream in(&file);
    QString text="";
    while(!in.atEnd()) {
        text+= in.readLine();
        text+="\n";
    }
    file.close();

    //filling the template
    text.replace("$source",itsDefinition->sphericalSourceImage.absoluteFilePath());

    //saving the template
    QFile fileout("tmp/sphere2cubic.pto");
    fileout.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&fileout);
    out << text;
    fileout.close();





    QString command2 = "nona -o ./tmp/cube ./tmp/sphere2cubic.pto";
    QProcess *myProcess = new QProcess(this);
    myProcess->execute(command2);
    delete myProcess;

    QImage img0("tmp/cube0000.tif");
    img0.save(itsDefinition->cubicSourceImages.at(0).absoluteFilePath(),0,100);
    QImage img1("tmp/cube0001.tif");
    img1.save(itsDefinition->cubicSourceImages.at(1).absoluteFilePath(),0,100);
    QImage img2("tmp/cube0002.tif");
    img2.save(itsDefinition->cubicSourceImages.at(2).absoluteFilePath(),0,100);
    QImage img3("tmp/cube0003.tif");
    img3.save(itsDefinition->cubicSourceImages.at(3).absoluteFilePath(),0,100);
    QImage img4("tmp/cube0004.tif");
    img4.save(itsDefinition->cubicSourceImages.at(4).absoluteFilePath(),0,100);
    QImage img5("tmp/cube0005.tif");
    img5.save(itsDefinition->cubicSourceImages.at(5).absoluteFilePath(),0,100);



}

void sceneCreator::makePreview(){
    sceneCreator* creator = this;
    sceneDefinition* def = creator->itsDefinition;

    QString nonaCommand = "nona -o ./tmp/"+ def->name+".jpg ./templates/cube2prev.pto";
    for(int j=0;j<def->cubicSourceImages.size();j++){
        nonaCommand+=" "+def->cubicSourceImages.at(j).absoluteFilePath();
    }
    qDebug()<<nonaCommand;

    QDir output = def->sceneDir;
    QString enblendCommand = "enblend -l1 --fine-mask --no-optimize -o ./tmp/"+def->name+"preview.jpg";
    for(int j=0;j<def->cubicSourceImages.size();j++){
        enblendCommand+=" ./tmp/"+def->name+".jpg"+"000";
        enblendCommand.append(j+'0');
        enblendCommand+=".tif";
    }
    qDebug()<<enblendCommand;

    QProcess *myProcess = new QProcess(this);
    myProcess->execute(nonaCommand);
    myProcess->execute(enblendCommand);
    delete myProcess;

    QString prev1 = "./tmp/"+def->name+"preview.jpg";
    IplImage* img1 = cvLoadImage(prev1.toUtf8().data());
    IplImage* img2 = cvLoadImage(prev1.toUtf8().data());

    cvSmooth( img1, img2, CV_GAUSSIAN, 19, 19 );

    int p[3];

    p[0] = CV_IMWRITE_JPEG_QUALITY;
    p[1] = 70;
    p[2] = 0;

    QString prev2 = output.absolutePath()+"/"+def->name+"preview.jpg";
    cvSaveImage(prev2.toUtf8().data(),img2,p);
}

#endif




QString sceneCreator::readTemplate(QString filePath){
    QFile file(filePath);
    if(!file.open(QIODevice::ReadOnly)) {
        return NULL;
    }

    QTextStream in(&file);
    QString text="";
    while(!in.atEnd()) {
        text+= in.readLine();
        text+="\n";
    }

    file.close();
    return text;
}

QString sceneCreator::fillTemplate(QString tmplt){
    for(int i=0;i<2;i++){
        tmplt.replace("$name",itsDefinition->name);
        tmplt.replace("$src",this->src.absolutePath());
        tmplt.replace("$includeScene","<include url=\"./$name/$name.xml\" />");
        if(itsDefinition->optionsPlugin){
            tmplt.replace("$optionsPlugin","<plugin name=\"options\" url=\"../../common/plugins/options.swf\" />");
        }
        else{
            tmplt.replace("$optionsPlugin","");
        }
        if(itsDefinition->editorPlugin){
            tmplt.replace("$editorPlugin","<plugin name=\"editor\" url=\"../../common/plugins/editor.swf\" align=\"bottom\" x=\"0\" y=\"16\" />");
        }
        else{
            tmplt.replace("$editorPlugin","");
        }
        if(itsDefinition->radarPlugin){
            tmplt.replace("$radarPlugin","<plugin name=\"radar\" opened=\"true\" url=\"../../common/plugins/radar.swf\" heading=\"33\"  align=\"lefttbottom\" x=\"226\"  y=\"11\" heading=\"95\" width=\"100\" height=\"100\"/>");
        }
        else{
            tmplt.replace("$radarPlugin","");
        }
        if(itsDefinition->logo){
            QString logoString = "                    <plugin";
            logoString += "                            name=\"logo\"";
            logoString += "                            keep=\"true\"";
            logoString += "                            url=\"./../common/images/vizyopano.png\"";
            logoString += "                            align=\"rightbottom\"";
            logoString += "                            x=\"10\"";
            logoString += "                            y=\"10\"";
            logoString += "                            onclick=\"openurl('http://www.vizyodizayn.com');\"";
            logoString += "                    />";
            tmplt.replace("$logo",logoString);
        }
        else{
            tmplt.replace("$logo","");
        }
        if(itsDefinition->autorotate){
            tmplt.replace("$autorotate","true");
        }
        else{
            tmplt.replace("$autorotate","false");
        }


        tmplt.replace("$pan",QString::number(itsDefinition->pan));
        tmplt.replace("$tilt",QString::number(itsDefinition->tilt));
    }
    return tmplt;
}

void sceneCreator::saveTemplate(QString tmplt,QString filePath){
    QFile file(filePath);
    file.open(QIODevice::WriteOnly | QIODevice::Text);
    QTextStream out(&file);
    out << tmplt;
    file.close();
}

void sceneCreator::options_checkbox_toggled(bool val){
    itsDefinition->optionsPlugin = val;
}
void sceneCreator::editor_checkbox_toggled(bool val){
    itsDefinition->editorPlugin = val;
}
void sceneCreator::radar_checkbox_toggled(bool val){
    itsDefinition->radarPlugin = val;
}
void sceneCreator::panAngleChanged(int pan){
    itsDefinition->pan = pan;
}
void sceneCreator::tiltAngleChanged(int tilt){
    itsDefinition->tilt = tilt;
}
void sceneCreator::logo_checkbox_toggled(bool val){
    itsDefinition->logo = val;
}
void sceneCreator::autorotate_checkbox_toggled(bool val){
    itsDefinition->autorotate = val;
}

int sceneCreator::emptyTmpFolder(){
    QString command = "rm -r ./tmp";
    QString command2 = "mkdir tmp";
    QProcess *myProcess = new QProcess();
    myProcess->execute(command);
    myProcess->execute(command2);
    delete myProcess;
}
